package cn.itsource.exception;

/**
 *	异常：
 *		1. 概念： 就是程序中一种不正常的情况。就是一种状态或标志，我们就是根据不同的异常类型，能够得知处理异常的方式。
 *		2. 异常分类：
		 *	Throwable（基类）
		 *		|
		 *		|---- Error 错误，我们程序无法处理。如，内层溢出，网络断线
		 *		|
		 *		|---- Exception 异常，我们可以通过程序处理
		 *				  |
		 *			   	  |---	RuntimeException 运行时异常，运行期才能知道
		 *				  |				|
		 *			   	  |			NullPointerException 空指针异常
		 *				  |
		 *				  |---	非运行时异常
		 *
 *		3. 异常在Java中的处理方式：
 *			在Java中处理异常的方式是：首先，发生异常的时候，会先看当前异常代码处是否有处理异常的代码，如果有，则会执行处理异常的代码
 *			处理完异常后，会继续向下执行。如果没有，则会向调用着抛出该异常，如果调用者有处理方式，则会正常执行，如果没有会继续再向调用者
 *			抛出，直到抛出给JVM为止，而JVM处理异常的方式是，打印异常信息到控制台，然后，退出JVM。
 *
 *		4. 处理异常方式：
 *				try{
 *					异常可能发生的代码
 *				}catch(可能的异常类1   变量){//当发生异常的时候，JVM会自动根据异常类型，创建一个异常对象，将对象的地址存放到变量中
 *					处理异常的操作：
 *					1. 打印异常的信息到控制台；
						//处理方式1 ：打印异常原因    一般处理后给前台页面返回，给用户提示问题原因 
						String message = e.getMessage();
						System.out.println(message);
						//2. 处理方式2：打印日志  推荐 给程序员看的，帮助程序员定位错误的位置
						e.printStackTrace();	
						
						//3. 处理方式3 ：异常类型和异常原因
						String str = e.toString();
						System.out.println(str);
						
					2. 可以把异常信息保存到一个文件中，可以持久的存储起来；； 因为实际项目有可能有很多异常打印到控制台，不能随时关注，这时就需要将日志保存，
					3. 可以抓住异常之后，向外在抛出给调用者，就是谁调用谁处理。
						用关键字throws,用在（）后｛｝前
						多个异常逗号隔开，顺序无所谓。
						
 *				}catch(可能的异常类2   变量){//注意：异常类型2 必须是异常类型1的父类或者不相干
 *					处理方式同上
 *				}.....
 *				finally{
 *					不管上面的上面的执行情况是怎样的，finally代码永远都会执行
 *					一般只是释放资源，不写业务逻辑代码。如，关流	
 *				}
 *
 *		5. 异常处理原则：
 *				1. 尽可能将异常细化处理，因为不同的异常处理方式不同
 *				2. 异常在catch的时候，必须保证父类异常在下面 ，子类异常在上面。或者几个异常没有任何关系的顺序无所谓
 */
public class ExceptionDemo3 {

	public static void main(String[] args) {
//		System.out.println("异常发生前代码2");
		
		
		int divide = divide("2","1");
		System.out.println(divide);
		System.out.println("异常发生后代码2=====>");
	}
	
	/**
	 * 求商方法
	 * @param n1
	 * @param n2
	 * @return
	 */
	public static int divide(String n1,String n2) {
		System.out.println("异常发生前代码1");
		int divide = 0;
		Integer integer = null;
		try {
			integer = new Integer(n1);
			System.out.println("-----------------------------------------异常发生之间");
			Integer integer2 = new Integer(n2);
			System.out.println("-----------异常发生之间------------------------------------------------");
			divide = integer/integer2;//因为上面如果在try中发生异常，这里integer是null，进行运算的时候还会发生异常，所有没有正常返回数据
		} catch (NumberFormatException e) {//只能捕捉当前异常类型或者当前异常类型的子类
			//一：打印到控制台
			//处理方式参考案例1
			System.out.println("亲，请注意您的参数中，不能有非数字相关的字符！！！");
			e.printStackTrace();//给程序员定位错误位置的
			
			//获取异常原因给用户
			e.getMessage();//给用户错误原因反馈的
			
			//二：通过io流记录到一个日志文件
		} catch (ArithmeticException e) {
			//处理方式参考案例1
			System.out.println("亲，除数不能为零！！！");
			e.printStackTrace();
		} catch (Exception e) {
			System.out.println("未知错误！");
			e.printStackTrace();
		} finally {
			//不管上面是否有异常，只要没有退出JVM，永远都会执行当前finally结构，但是一般只写释放资源操作：如关闭IO中流，释放锁资源
			
//			return 1;//一般不会把功能语句写在此处，如果返回一个值
			System.out.println("不管上面是否有异常，只要没有退出JVM，永远都会执行当前finally结构，但是一般只写释放资源操作：如关闭IO中流，释放锁资源");
		}
		System.out.println("异常发生后代码1=====>");
		return divide;
	}
}
